<template>
  <div :style="styleObj" class="Box">
    <div class="block">
      <div class="Lbox" v-show="iconShow">
        <span class="demonstration">显示数据时长(小时):</span>
        <el-slider
          v-model="dataPeriod"
          :min="1"
          :max="72"
          @change="sliderChange"
        ></el-slider>
      </div>
      <div class="Rbox">
        <el-tooltip content="选择" placement="top" effect="light">
          <i class="el-icon-setting Ricon" @click="IconClick"></i>
        </el-tooltip>
        <el-tooltip content="刷新" placement="top" effect="light">
          <i class="el-icon-refresh Ricon" @click="parseLineSetting(true)"></i>
        </el-tooltip>
      </div>
    </div>

    <!-- <v-chart :options="options" autoresize /> -->
    <div class="mychart" ref="chart" :key="key"></div>
  </div>
</template>

<script>
import store from "@/store/index.js";
import {
  setMessageCallback,
  publishMsg,
  removeMessageCallback,
  checkSpecialId,
} from "@/mqtt";
import { SCADA_MSG } from "@/mqtt/msg.js";
import moment from "moment";
export default {
  name: "WidgetLineTimeChart",
  components: {},
  props: {
    value: Object,
    ispreview: Boolean,
    widgetIndex: Number,
    pageId: String,
  },
  data() {
    return {
      key: 1,
      chart: null,
      options: {
        grid: {},
        color: [],
        title: {
          text: "",
          textStyle: {
            color: "#fff",
          },
        },
        axisPointer: {
          label: {
            // color: "#0099ff",
            show: true,
            precision: "auto",
            backgroundColor: "rgba(0, 0, 0, 0)",
          },
        },
        tooltip: {
          trigger: "axis",
        },
        legend: {
          textStyle: {
            color: "#fff",
          },
        },
        xAxis: {
          type: "time",
          splitLine: {
            show: false,
          },
          data: [],
          axisLabel: {
            show: true,
          },
        },
        yAxis: {
          type: "value",
          axisLabel: {
            show: true,
          },
        },
        //这个配置是 将数据曲线下载为一张图片
        // toolbox: {
        //   show: true,
        //   feature: {
        //     saveAsImage: {},
        //   },
        // },
        series: [
          {
            name: "",
            type: "line",
            showSymbol: true,
            data: [],
            markPoint: {
              data: [
                // { type: "max", name: "最大值" },
                // { type: "min", name: "最小值" },
              ],
            },
          },
          {
            name: "",
            type: "line",
            showSymbol: true,
            data: [],
            markPoint: {
              data: [
                // { type: "max", name: "最大值" },
                // { type: "min", name: "最小值" },
              ],
            },
          },
          {
            name: "",
            type: "line",
            showSymbol: true,
            data: [],
            markPoint: {
              data: [
                // { type: "max", name: "最大值" },
                // { type: "min", name: "最小值" },
              ],
            },
          },
          {
            name: "",
            type: "line",
            showSymbol: true,
            data: [],
            markPoint: {
              data: [
                // { type: "max", name: "最大值" },
                // { type: "min", name: "最小值" },
              ],
            },
          },
          {
            name: "",
            type: "line",
            showSymbol: true,
            data: [],
            markPoint: {
              data: [
                // { type: "max", name: "最大值" },
                // { type: "min", name: "最小值" },
              ],
            },
          },
        ],
      },
      optionsStyle: {}, // 样式
      optionsData: {}, // 数据
      optionsCollapse: {}, // 图标属性
      optionsSetup: {},
      dataNum: 100, //数据点数
      dataSetting: [],
      lengendName: [],
      timer: [],
      dataPeriod: 2,
      iconShow: false,
      mySpecialId: "",
      timeLineChart: {},
      update: null,
    };
  },
  created() {
    this.initKey();
  },
  computed: {
    styleObj() {
      return {
        position: this.ispreview ? "absolute" : "static",
        width: this.optionsStyle.width + "px",
        height: this.optionsStyle.height + "px",
        left: this.optionsStyle.left + "px",
        top: this.optionsStyle.top + "px",
        background: this.optionsSetup.background,
      };
    },
  },
  watch: {
    value: {
      handler(val) {
        // console.log(val, "改变值");
        this.optionsStyle = val.position;
        this.optionsData = val.data;
        this.optionsCollapse = val.collapse;
        this.optionsSetup = val.setup;
        this.editorOptions(true);
      },
      deep: true,
    },
    options: {
      handler(val) {
        // console.log(val, "options改变值", this.key);
        this.resetChartOption();
      },
      deep: true,
    },
  },
  mounted() {
    setMessageCallback(this.onMsg);
    this.optionsStyle = this.value.position;
    this.optionsData = this.value.data;
    this.optionsCollapse = this.value.collapse;
    this.optionsSetup = this.value.setup;
    this.editorOptions(true);
    // console.log("mounted");
  },
  destroyed() {
    for (let i = 0; i < 5; i++) {
      if (this.timer[i] != null) {
        clearInterval(this.timer[i]);
        this.timer[i] = null;
      }
    }

    removeMessageCallback(this.onMsg);
  },
  methods: {
    IconClick() {
      this.iconShow = !this.iconShow;
    },
    sliderChange(val) {
      let msg = {
        webMsgType: 1022,
        funCode: 6,
        data: {
          id: this.pageId,
          widgetIndex: this.widgetIndex,
          setup: { dataPeriod: val },
        },
      };
      this.mySpecialId = publishMsg(msg);
      store.commit("updateWidget", msg.data);
      this.parseLineSetting(true);
    },
    initKey() {
      this.key = Math.trunc(Math.random() * 1000);
    },
    getXAxisData(count, long) {
      let time = new Date();
      time = time - 2 * 60 * 60 * 1000;
      let categoryData = [];
      for (let i = 0; i <= count; i++) {
        categoryData.push(moment(time).format("MM-DD HH:mm:ss"));
        time += long;
      }
      return categoryData;
    },
    restartInterval() {
      if (this.dataSetting.length > 0) {
        for (let i = 0; i < 5; i++) {
          if (this.timer[i] != null) {
            clearInterval(this.timer[i]);
            this.timer[i] = null;
          }
          this.timer[i] = setInterval(() => {
            let dataId = this.dataSetting[i].dataId;
            let dataType = this.dataSetting[i].dataSetNameId;
            if (dataType != "" && dataId != "") {
              if (this.timeLineChart.hasOwnProperty(dataId)) {
                this.options.series[i].data = this.timeLineChart[dataId];
                this.options.series[i].name = this.timeLineChart[dataId][0][2];
                this.lengendName.push(this.timeLineChart[dataId][0][2]);
              } else {
              }
            } else {
              this.options.series[i].data = [];
              clearInterval(this.timer[i]);
              this.timer[i] = null;
            }
          }, 100);
        }
      } else {
        this.$message.warning("请选择数据！！！");
      }
    },
    //去重
    setUnique(arr) {
      let newArr = [];
      arr.forEach((item) => {
        return newArr.includes(item) ? "" : newArr.push(item);
      });
      return newArr;
    },
    editorOptions(flag) {
      this.dataPeriod = this.value.setup.dataPeriod;
      this.parseLineSetting(flag);
      this.setOptionsTitle();
      this.setOptionsX();
      this.setOptionsY();
      this.setOptionsTop();
      this.setOptionsTooltip();
      this.setOptionsMargin();
      this.setOptionsColor();
      this.setOptionsLegend();
      this.initChart();
      this.restartInterval();
    },
    initChart() {
      if (this.chart != null && this.chart != "" && this.chart != undefined) {
        this.chart.dispose(); //销毁
      }
      this.chart = this.$echarts.init(this.$refs.chart);
      this.chart.clear();
      this.chart.setOption(this.options);
      this.chart.resize();
    },
    resetChartOption() {
      this.chart.clear();
      this.chart.setOption(this.options);
      this.chart.resize();
    },
    GetDateStr(days) {
      var date = new Date();
      date.setDate(date.getDate() + days); //获取AddDayCount天后的日期

      var Y = date.getFullYear();
      var MM = date.getMonth() + 1;
      var M = ""; //获取当前月份的日期
      if (MM >= 1 && MM <= 9) {
        M = "0" + MM;
      } else {
        M = MM;
      }
      var D = date.getDate() >= 10 ? date.getDate() : "0" + date.getDate();
      var H = date.getHours() >= 10 ? date.getHours() : "0" + date.getHours(); //获取系统时间
      var m =
        date.getMinutes() >= 10 ? date.getMinutes() : "0" + date.getMinutes(); //分
      var s =
        date.getSeconds() >= 10 ? date.getSeconds() : "0" + date.getSeconds(); //秒
      return Y + "-" + M + "-" + D + " " + H + ":" + m + ":" + s;
    },
    checkDataListIsExist(dataId) {
      if (store.state.timeLineChart.hasOwnProperty(dataId)) {
        return true;
      } else {
        return false;
      }
    },

    reqDataList(dataType, dataId) {
      // console.log(dataId, dataType);
      let msg = {
        webMsgType: 1020,
        funCode: 0,
      };
      let obj = {};
      this.$set(obj, "id", dataId);
      switch (dataType) {
        case "yc":
          this.$set(obj, "from", "data-yc");
          break;
        case "ym":
          this.$set(obj, "from", "data-ym");
          break;
        case "task":
          this.$set(obj, "from", "data-task");
          break;
        default:
          return;
      }
      this.$set(obj, "endTime", "now");
      this.$set(obj, "beginTime", this.GetDateStr(-1));
      msg.data = obj;
      this.mySpecialId = publishMsg(msg);
    },

    parseLineSetting(force) {
      if (this.optionsData.dataType === "dynamicData") {
        if (this.optionsData.dynamicData.hasOwnProperty("chartProperties")) {
          this.dataSetting = this.optionsData.dynamicData.chartProperties;
          this.lengendName = [];
          for (let i = 0; i < this.dataSetting.length; i++) {
            this.options.series[i].name = "";
            this.options.series[i].data = [];
            let el = this.dataSetting[i];
            let dataId = el.dataId;
            let dataType = el.dataSetNameId;
            if (dataType != "" && dataId != "") {
              if (force) {
                this.reqDataList(dataType, dataId);
              } else {
                if (!this.timeLineChart.hasOwnProperty(dataId)) {
                  this.reqDataList(dataType, dataId);
                }
              }
            }
          }
        }
      }
    },
    resetTimeLineChartData(id) {
      this.timeLineChart[id] = [];
    },
    //添加定时时序图数据
    addTimeLineChartData(data) {
      if (!this.timeLineChart.hasOwnProperty(data.id)) {
        this.timeLineChart[data.id] = [];
      }
      this.timeLineChart[data.id].push(data.data.value);
    },
    //对时序图数据处理
    removeTimeLineChartData(cfg) {
      let id = cfg.id;
      let hours = cfg.dataPeriod;
      // console.log("时序图长度", hours);

      if (this.timeLineChart.hasOwnProperty(id)) {
        let tsNow = new Date().getTime();
        let tsAgo = tsNow - hours * 3600 * 1000;
        let canRemoveCount = 0;
        for (let i = 0; i < this.timeLineChart[id].length; i++) {
          let data = this.timeLineChart[id][i];
          // console.log(data, "data");
          let tsData = new Date(data[0]).getTime();
          if (tsData > tsAgo) {
            canRemoveCount = i;
            break;
          }
        }

        if (canRemoveCount > 0) {
          this.timeLineChart[id].splice(0, canRemoveCount);
        }
      }
    },

    setOptionsTitle() {
      const optionsSetup = this.optionsSetup;
      const title = {};
      title.text = optionsSetup.titleText;
      title.show = optionsSetup.isNoTitle;
      title.left = optionsSetup.textAlign;
      title.textStyle = {
        color: optionsSetup.textColor,
        fontSize: optionsSetup.textFontSize,
        fontWeight: optionsSetup.textFontWeight,
      };
      title.subtext = optionsSetup.subText;
      title.subtextStyle = {
        color: optionsSetup.subTextColor,
        fontWeight: optionsSetup.subTextFontWeight,
        fontSize: optionsSetup.subTextFontSize,
      };
      this.options.title = title;
    },
    // X轴设置
    setOptionsX() {
      const optionsSetup = this.optionsSetup;
      const xAxis = {
        type: "time",
        // show: optionsSetup.hideX, // 坐标轴是否显示
        // name: optionsSetup.xName, // 坐标轴名称
        nameTextStyle: {
          color: optionsSetup.nameColorX,
          fontSize: optionsSetup.nameFontSizeX,
        },
        nameRotate: optionsSetup.textAngle, // 文字角度
        inverse: optionsSetup.reversalX, // 轴反转
        axisLabel: {
          show: true,
          // formatter: "{MM}-{DD} {HH}:{mm}:{ss}",
          formatter: function (val) {
            let now = new Date(val);
            let hour = now.getHours();
            let min = now.getMinutes();
            if (hour < 10) {
              hour = "0" + hour;
            }
            if (min < 10) {
              min = "0" + min;
            }
            return (
              [now.getMonth() + 1, now.getDate()].join("-") +
              " " +
              [hour, min].join(":")
            );
          },
          // interval: optionsSetup.textInterval, // 文字间隔
          // rotate: optionsSetup.textAngle, // 文字角度
          textStyle: {
            color: optionsSetup.Xcolor, // x轴 坐标文字颜色
            fontSize: optionsSetup.fontSizeX,
          },
        },
        minInterval: 5 * 60 * 1000,
        axisLine: {
          show: true,
          lineStyle: {
            color: optionsSetup.lineColorX,
          },
        },
        splitLine: {
          show: optionsSetup.isShowSplitLineX,
          lineStyle: {
            color: optionsSetup.splitLineColorX,
          },
        },
      };
      this.options.xAxis = xAxis;
    },
    // Y轴设置
    setOptionsY() {
      const optionsSetup = this.optionsSetup;
      const yAxis = {
        type: "value",
        scale: optionsSetup.scale,
        splitNumber: optionsSetup.splitNumber, // 均分
        show: optionsSetup.isShowY, // 坐标轴是否显示
        name: optionsSetup.textNameY, // 坐标轴名称
        nameTextStyle: {
          // 别名
          color: optionsSetup.nameColorY,
          fontSize: optionsSetup.namefontSizeY,
        },
        inverse: optionsSetup.reversalY, // 轴反转
        axisLabel: {
          show: true,
          rotate: optionsSetup.ytextAngle, // 文字角度
          textStyle: {
            color: optionsSetup.colorY, // y轴 坐标文字颜色
            fontSize: optionsSetup.fontSizeY,
          },
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: optionsSetup.lineColorY,
          },
        },
        splitLine: {
          show: optionsSetup.isShowSplitLineY,
          lineStyle: {
            color: optionsSetup.splitLineColorY,
          },
        },
      };
      this.options.yAxis = yAxis;
    },
    // 折线设置
    setOptionsTop() {
      const optionsSetup = this.optionsSetup;
      let series = this.options.series;
      for (const key in series) {
        if (series[key].type == "line") {
          series[key].showSymbol = optionsSetup.markPoint;
          series[key].symbolSize = optionsSetup.pointSize;
          series[key].smooth = optionsSetup.smoothCurve;
          // series[key].area = optionsSetup.area;
          if (optionsSetup.area) {
            series[key].areaStyle = {
              opacity: optionsSetup.areaThickness / 100,
            };
          } else {
            series[key].areaStyle = {
              opacity: 0,
            };
          }

          series[key].lineStyle = {
            width: optionsSetup.lineWidth,
          };
          series[key].label = {
            show: optionsSetup.isShow,
            position: "top",
            distance: 10,
            fontSize: optionsSetup.fontSize,
            color: optionsSetup.subTextColor,
            fontWeight: optionsSetup.fontWeight,
          };
        }
      }
      this.options.series = series;
    },
    // tooltip 设置
    setOptionsTooltip() {
      const optionsSetup = this.optionsSetup;
      const tooltip = {
        trigger: "axis",
        axis: "auto",
        snap: true,
        show: true,
        textStyle: {
          color: optionsSetup.lineColor,
          fontSize: optionsSetup.tipsFontSize,
        },
        axisPointer: {
          type: "cross",
          axis: "auto",
          show: true,
          crossStyle: {
            color: "#fff",
            type: "dotted",
          },
          // shadowStyle: {
          //   color: rgba(0),
          // },
          //   type: "shadow", //   label: { //     show: true, //   },
        },
      };
      this.options.tooltip = tooltip;
    },
    // 边距设置
    setOptionsMargin() {
      const optionsSetup = this.optionsSetup;
      const grid = {
        left: optionsSetup.marginLeft,
        right: optionsSetup.marginRight,
        bottom: optionsSetup.marginBottom,
        top: optionsSetup.marginTop,
        containLabel: true,
      };
      this.options.grid = grid;
    },
    //图例设置
    setOptionsLegend() {
      const optionsSetup = this.optionsSetup;
      const legend = this.options.legend;
      legend.show = optionsSetup.isShowLegend;
      legend.left = optionsSetup.lateralPosition;
      legend.top = optionsSetup.longitudinalPosition;
      legend.bottom = optionsSetup.longitudinalPosition;
      legend.orient = optionsSetup.layoutFront;
      legend.textStyle = {
        color: optionsSetup.lengedColor,
        fontSize: optionsSetup.lengedFontSize,
      };
      legend.itemWidth = optionsSetup.lengedWidth;
      legend["data"] = this.lengendName;
      this.options.legend = legend;
    },
    // 图例颜色修改
    setOptionsColor() {
      const optionsSetup = this.optionsSetup;
      const customColor = optionsSetup.customColor;
      if (!customColor) return;
      const arrColor = [];
      for (let i = 0; i < customColor.length; i++) {
        arrColor.push(customColor[i].color);
      }
      this.options.color = arrColor;
      this.options = Object.assign({}, this.options);
    },
    /**
     *
     * @param {判断该id是否和datasetting中的id一致} id
     */
    isMyData(id) {
      let bHasId = false;
      for (let i = 0; i < this.dataSetting.length; i++) {
        if (this.dataSetting[i].dataId == id) {
          bHasId = true;
          break;
        }
      }
      return bHasId;
    },
    onMsg(topic, msg) {
      // console.log("topology onMsg", msg);
      switch (msg.webMsgType) {
        case SCADA_MSG.scada_param_dashboard:
          {
            if (msg.funCode == 6) {
              if (checkSpecialId(msg)) {
                console.log("设置显示数据周期个数成功！");
              }
            }
          }
          break;
        case SCADA_MSG.scada_param_data:
          // if (this.mySpecialId == msg["specialId"]) {
          {
            if (msg.funCode == 0) {
              if (msg.retCode != 0) {
                this.$message.error(msg.retMsg);
              } else {
                let data = msg.data;
                let dataId = data.id;
                let name = data.name;
                let unit = data.unit;
                let dataList = data.data;
                let isReq = this.isMyData(dataId);
                if (isReq) {
                  this.timeLineChart[dataId] = [];
                  for (let i = 0; i < dataList.length; i++) {
                    let obj = {};
                    obj.name = name;
                    obj.unit = unit;
                    obj.id = dataId;
                    obj.data = {};
                    obj.data.value = [];
                    let datetime = dataList[i].datetime;
                    obj.data.value.push(datetime);
                    obj.data.value.push(dataList[i].value);
                    obj.data.value.push(name);
                    this.addTimeLineChartData(obj);
                  }
                  let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                  this.removeTimeLineChartData(cfg);
                }
              }
            }
          }
          // }
          break;
        case SCADA_MSG.scada_param_yc:
          {
            switch (msg.funCode) {
              case 2:
                {
                  let dataList = msg.data;
                  for (let i = 0; i < dataList.length; i++) {
                    let data = dataList[i];
                    let dataId = data.id;
                    let value = data.value;
                    let datetime = data.update_time;
                    if (this.timeLineChart.hasOwnProperty(dataId)) {
                      let obj = {};
                      obj.id = dataId;
                      obj.data = {};
                      obj.data.value = [];
                      obj.data.value.push(datetime);
                      obj.data.value.push(value);
                      this.addTimeLineChartData(obj);
                    }
                    if (this.isMyData(dataId)) {
                      let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                      this.removeTimeLineChartData(cfg);
                    }
                  }
                }
                break;
            }
          }
          break;
        case SCADA_MSG.scada_param_ym:
          {
            switch (msg.funCode) {
              case 2:
                {
                  let dataList = msg.data;
                  for (let i = 0; i < dataList.length; i++) {
                    let data = dataList[i];
                    let dataId = data.id;
                    let value = data.value;
                    let datetime = data.update_time;
                    if (this.timeLineChart.hasOwnProperty(dataId)) {
                      let obj = {};
                      obj.id = dataId;
                      obj.data = {};
                      obj.data.value = [];
                      obj.data.value.push(datetime);
                      obj.data.value.push(value);
                      this.addTimeLineChartData(obj);
                    }
                    if (this.isMyData(dataId)) {
                      let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                      this.removeTimeLineChartData(cfg);
                    }
                  }
                }
                break;
            }
          }
          break;
        case SCADA_MSG.scada_param_task:
          {
            switch (msg.funCode) {
              case 4:
                {
                  let data = msg.data;
                  let dataId = data.id;
                  let value = data.value;
                  let datetime = data.update_time;
                  if (this.timeLineChart.hasOwnProperty(dataId)) {
                    let obj = {};
                    obj.id = dataId;
                    obj.data = {};
                    obj.data.value = [];
                    obj.data.value.push(datetime);
                    obj.data.value.push(value);
                    this.addTimeBarChartData(obj);
                  }
                  if (this.isMyData(dataId)) {
                    let cfg = { id: dataId, dataPeriod: this.dataPeriod };
                    this.removeTimeBarChartData(cfg);
                  }
                }
                break;
            }
          }
          break;
        default:
          break;
      }
    },
  },
};
</script>

<style scoped lang="scss">
.Box {
  // position: relative;
}

.block {
  display: flex;
  align-items: center;
  width: 90%;
  position: relative;

  .Lbox {
    display: flex;
    flex: 1;
    height: 30px;
    margin-top: -30px;

    .demonstration {
      width: 150px;
      line-height: 36px;
      margin-right: 20px;
    }

    .el-slider {
      flex: 1;

      ::v-deep .el-slider__runway {
        height: 5px;
        background-color: #0099ff;
      }
    }
  }

  .Rbox {
    position: absolute;
    top: -20px;
    right: -50px;
    width: 50px;
    display: flex;

    i {
      cursor: pointer;
      color: #0099ff;
      margin: 0 5px;
    }
  }
}

.mychart {
  width: 100%;
  height: 100%;
  overflow: hidden;
  // div {
  //   width: 100% !important;
  //   height: 100% !important;
  // }
}
</style>
